require "Common/define"
require "Common/ClassType"
require "Common/Class"
require "Common/VectorUtils"
require "Logic/CtrlManager"
require "Logic/Config"
require "Common/functions"
require "staticData"
require "Net/NetMsgDecoder"
require "Net/Http"
require "Logic/OffLine"
require "View/UIBase/UIBase"

require "Logic/list"
require "Net/event"
require "Net/systemevent"
require "LocalServer/LocalServerConfig"

--require "Data/DataUtils"

-- require "Net/GlobalEvent"
require "proto/server/message/ReqHeartMessage"
require "Common/EnumConst"
require "Logic/ObjUtil"
require "model/RedHintModel"
require 'FairyGUI'
require "Logic/ItemData"
require "Logic/BattlePlaybackManager"
require "Logic/ConnectManager"
require "Logic/AudioManager"
require "Logic/TAManager"
require "Logic/SDKManager"
require "Logic/TablePool"
require "Logic/ComponentPoolMgr"
require "Battle/BattleSceneCacheResouce"
require "RedRob/RobInclude"
require "TurnBasedStrategy/Include"
require "Logic/LanguageManager"
require "Common/LuaUIMgr"
--管理器--
Game = {};
local this = Game;

this.itemObj = nil;
this.skillObj = nil;
this.emailItemObj = nil;
this.RoleId = nil;
this.sendPingTime = 0;
this.resetSendTime = 0;
this.checkConnect = false;
this.sendTimes = 0;
this.reConnect = false;
this.reConnecting = false;
this.curMapId = 0;
this.offlineTime = 0;
local loadedNum = 0;
local loadMaxRes = 0;
local UpdateInterval = 3.0;
local LastInterval = 0;
local Frames = 0;
local Fps;
local ShowFps = false;

--初始化完成，发送链接服务器信息--
function Game.OnInitOK()
	-- 在lua中开启FGUI批处理更能灵活控制
	--GRoot.inst.rootContainer.fairyBatching = true
	Input.multiTouchEnabled = false
	Config.RemoteConfig = decodeJsonStrToTabel(YanhuaMMO.AppConst.remoteConfigStr) or {}
	-- if panelMgr.UIDownLoad then panelMgr.UIDownLoad:SetActive(false)end
	utimer.delayCall(function () showUI(PanelNames.UILogin) end, 1000)
end

function Game.OnInitOKEditor()
	Game.OnInitOK()

	utimer.delayCall(function () DestoryUI(PanelResNames.UILogin) end, 1010)--OnInitOKEditor是技能编辑器掉的，这一行临时应对Game.OnInitOK里的utimer.delayCall；
	require ("View/"..PanelNames.UIRedDots)
	local name, packageName = getUIName(PanelNames.Headbar)
	panelMgr:CreatePanel(name, packageName,nil,nil,nil,false)
end

function Game.GetGlobal()
	return G.dataTable["Global"];
end

-- function Game.GetSound()
-- 	return G.dataTable["T_sound"];
-- end

-- function Game.PlayUISoundByName(value)
-- 	playCommonByName(value);
-- end

-- function Game.PlayUISoundByType(value)
-- 	playCommonByType(value);
-- end

function Game.GetBGVolumeMax()
	return G.dataTable["t_global"]["40"].f_int_value;
end

function Game.GetSoundVolumeMax()
	return G.dataTable["t_global"]["41"].f_int_value;
end

function Game.GetCVVolumeMax()
	return G.dataTable["t_global"]["42"].f_int_value;
end

function Game.GetSoundPathByUIName(name,para)
	-- local table = G.dataTable["t_bgm"];
    -- for k,v in pairs(table) do
	-- 	if v.f_UIPrefab == name then
    --         return v[para];
    --     end
    -- end
    -- return nil;
end

function Game.Update()
	UpdateEventSystem(Time.deltaTime)
	--Game.UpdateGloalEvent();
	--[[
	if this.ShowFps then
		LastInterval = LastInterval + Time.unscaledDeltaTime;
		Frames = Frames + 1;
		if LastInterval > UpdateInterval then
			Fps = Frames / LastInterval;  
			LastInterval = 0;
			Frames = 0;
			--log(Fps);
			FireEvent(Config.EventType.Fresh_FPS, true, Fps);
		end
	end
	]]

	this.offlineTime = this.offlineTime + Time.unscaledDeltaTime;
end

this.disConnect = false;
this.waitTime =0;
function Game.Heart()
	--log("Game.Heart")
	
	print("timer start");
	if this.timer == nil then
		this.timer = Timer.New(function ()
			this.waitTime = this.waitTime+1;
			if this.waitTime<3 and Config.serverTime>0 then
				Config.serverTime = Config.serverTime+1000;
				return;
			end
			this.waitTime = 0;

			--发送心跳
			loginHandler.R_Heart()

			local delta = os.time() - this.sendPingTime

			if this.reConnecting == false and this.sendPingTime ~= 0 and delta > 9 then
				printError("reconnect");
				this.reConnecting = true;
				ConnectManager.ForceReconnect()
			else
				if this.reConnecting == false and dungeonHandler.sendBossTime ~= 0 and os.time() - dungeonHandler.sendBossTime > 9 then
					printError("reconnect");
					this.reConnecting = true;
					ConnectManager.ForceReconnect()
				end
			end

		end,1,-1,true);
	end
	this.timer:Start()
end

function Game.stopHeart()
    if this.timer ~= nil then
        this.timer:Stop();
    end
end
--function Game.CheckDisConnect()
--
--	this.sendTimes = this.sendTimes+1;
--	--尝试3次以后断开连接
--	if this.sendTimes > 4 then
--		this.timer:Stop();
--        --mapMgr:pauseByGuide(0);
--
--        coroutine.start(this.reConnectSocket);
----[[		local pop = CtrlManager.GetCtrl(PanelNames.UICommonPop);
--		pop.Init("3",function(b)
--			this.sendPingTime = 0;
--			if not b then
--				this.timer:Start();
--				return;
--			end
--			local head = CtrlManager.GetCtrl(PanelNames.UIHeadInfo);
--			if head then
--				if Util.NetAvailable then
--					head.OnChangeAccClick();
--				else
--					UISysTips.AddMsg("无网络信号");
--					this.timer:Start();
--				end
--			end
--			this.sendTimes = 0;
--		end);]]
--		return;
--	end
--
--	if Util.NetAvailable then
--		--this.ConnectLoginServer();
--		--this.sendPingTime = 0;
--	else
--		UISysTips.AddMsg("无网络信号");
--	end
--end


--每帧调用
function Game.UpdateGloalEvent()
	
	if this.RoleId == nil then
		return;
	end

	if not this.disConnect then return end;
	if this.reConnect then return end;
	
	
	if this.checkConnectLSvr then
		if AppConst.connect then
			this.LoginAccount();
			this.checkConnectLSvr = false;
		end
	end
	
	if this.checkConnectGServer then
		if AppConst.connect then
			if this.connectInfo ~= nil and G.serverData["connectInfo"] ~= nil then
				local loginId = G.serverData["connectInfo"]["loginId"]
				local verifyStr = G.serverData["connectInfo"]["verifyStr"]
				
				SendMsg.Send(Config.msg_type.send_loginGame,loginId,verifyStr,tonumber(this.RoleId),3,0,0,0)

				this.reConnect = true;
				this.sendTimes = 0;	
			end
			this.checkConnectGServer = false;
		end
		
	end
end

function Game.LoginAccount()
	local user = Util.GetUserName();
    local pass = Util.GetPassword();
	local sid = AppConst.ServerId;
	SendMsg.Send(Config.msg_type.send_login,user,pass,sid,0,1,"");
	
	print(user,pass,sid)
	G._ConnectServer = this.ConnectGameServer;
end

function Game.ConnectGameServer()
	WebMsgMgr:DisConnect()
	WebMsgMgr:ConnectServer(AppConst.SocketAddress,AppConst.SocketPort)
	this.checkConnectGServer = true;
	
	--清空场景数据
	--mapMgr:ClearScene();
    MercenaryModel.resetMercenary();
	collectgarbage("collect");
	 
    --特殊处理

    GuildWarManager.Reset()
	G._ConnectServer = nil;
end

function Game.ConnectLoginServer()
	
	if this.connectInfo == nil then
		this.connectInfo = clone(G.serverData["connectInfo"])
	end
	if this.curMapId == nil then
		this.curMapId = logicMgr.MapManager.getMapId();
	end
	--清空服务端数据
	G.serverData = {};
	--断开连接
	WebMsgMgr:DisConnect();
	WebMsgMgr:ConnectServer(Config.login_server_id,Config.login_server_port, Config.Password);
	this.checkConnectLSvr = true;

end

function Game.coroutineReconnect()

    coroutine.start(this.reConnectSocket);

end
function Game.reConnectSocket()

    UIWaiting.ShowWaiting();
    WebMsgMgr:DisConnect();
    --coroutine.wait(2);

    if this.timer ~= nil then
        this.timer:Stop();
    end
    local waitNetState = 0;
    while not Util.NetAvailable and waitNetState < 5 do
        coroutine.wait(0.1);
        waitNetState = waitNetState + 0.1;
    end

    coroutine.wait(6);
    UIWaiting.ShowWaiting();

    if Util.NetAvailable and logicMgr.LoginManager.GetDefaultServerInfo() ~= nil then
        WebMsgMgr:ConnectServer(logicMgr.LoginManager.GetLoginRecordIP(), logicMgr.LoginManager.GetLoginRecordPort(), Config.Password);

        local waittime = 0;
        while not AppConst.connect and waittime < 6 do
            coroutine.wait(0.1);
            waittime = waittime + 0.1;
        end

        --print("connet server"..AppConst.connect)

        if AppConst.connect then
            Config.autoLogin = true;
			logicMgr.LoginManager.SetLoginType(EnumConst.LoginState.Login)
			loginHandler.R_LoginUser()
            UIWaiting.HideWaiting();
        else
            this.showReloginAlert();
        end
    else
        this.showReloginAlert();
    end

end

function Game.showReloginAlert()

    local pop = CtrlManager.GetCtrl(PanelNames.UICommonPop);
    pop.Init("3",function(b)
        this.sendPingTime = 0;
        if not b then
            this.timer:Start();
            return;
        end
        local head = CtrlManager.GetCtrl(PanelNames.UIHeadInfo);
        if head then
            if Util.NetAvailable then
                head.OnChangeAccClick();
            else
                UISysTips.AddMsg("无网络信号");
                this.timer:Start();
            end
        end
        this.sendTimes = 0;
    end);
end

function Game.getUIParent(uiName)
	local layer = PanelLayers[uiName]
	if not layer then
		layer =  "MainParent"
	end
	return layer;
end

--- 重新启动
function Game.ResetStart(isAutoLogin)
	WWISE.WwiseBehavior.LoadBankAsync("Login_Bank",nil)
	HelperFunc.UnloadBattleRes()
	this.reLogin = true;
	Config.SDKUserId = "";
	logicMgr.LoginManager.notice_callback = nil
	--清空服务端数据
	G.serverData = {};

	logicMgr.ActiveManager.sevenDayInfotab = {}
	if UILoading then 
		UILoading.mapLoadFinish = false;
	end
	--MercenaryModel.resetData();
	if UIRedDots then UIRedDots.Destory() end
	if FightManager and FightManager.fightBegin then
		UIRoundBattle.forceClose();
	end
	WebSocketMgr.GetInstance():Close();
	logicMgr.GuideMgr.OnDestroy()
	--隐藏所有UI
	local isShowLogin = true
	destroyAllUIIgnore(function(name)
		if name == PanelResNames.UILogin then 
			if isOpenUI(name) then 
				isShowLogin = false
				return true
			end
		end
	end)
	if BattleScene then
		BattleScene.destroyScene()
	end
	BattleSceneCacheResouce:OnDestroy()
	CtrlManager.ClearLuaTable()
	RedRob.ClientBattle.OnDestroy()
	CloseAllEvent()
	
	resMgr:ClearBattleResRef()
	HelperFunc.UnloadBattleRes()

	collectgarbage("collect");
	--显示login界面
	if isAutoLogin then
		local login = CtrlManager.GetCtrl(PanelNames.UILogin)
		if login ~= nil then
			login.changeAccount = true
		end
	end
	if isShowLogin then showUI(PanelNames.UILogin) end
	DestoryUI(PanelNames.UIScreenEffect)
	showUI(PanelNames.UIScreenEffect);

	Game.sendPingTime = 0;

	--断开连接
	if chatHandler then
		chatHandler.ClearBulletData()
	end

	TAManager.LogoutAndExit()
	
	if plunderHandler then
		plunderHandler.ResetData()
	end

	LoginManager.init()

	Config.isU8sdkLoginOut = true

	if AppConst.connect then
		WebMsgMgr:DisConnect()
	end
end

function Game.OnApplicationQuit()
	logicMgr.TATrackCollect.OnApplicationQuit()
end

function Game.OnApplicationPause()
	logicMgr.TATrackCollect.OnApplicationQuit()
end
function Game.OnApplicationFocus(focus)
	if focus then
		logicMgr.GuideMgr.CheckGuide(true)
	end
end